package sale.wxb.loveshopping.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import sale.wxb.loveshopping.constant.RedisConst;
import sale.wxb.loveshopping.entity.common.ResultException;
import sale.wxb.loveshopping.entity.model.SysUser;
import sale.wxb.loveshopping.entity.yml.YmlConfig;
import sale.wxb.loveshopping.service.ISysUserService;
import sale.wxb.loveshopping.service.IVerifyCodeService;
import sale.wxb.loveshopping.utils.EMailUtils;
import sale.wxb.loveshopping.utils.RedisUtil;

import javax.servlet.http.HttpServletRequest;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Value("${spring.mail.verifyCodeTemplate}")
    private String messageTemplate;
    @Autowired
    private YmlConfig ymlConfig;
    @Autowired
    private EMailUtils eMailUtils;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private HttpServletRequest httpServletRequest;
    private final RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);

    @Override
    public Boolean sendVerifyCodeByEMail(String email, boolean registered) {
        if (registered && !ObjectUtils.isEmpty(sysUserService.getUserByEmail(email))) {
            throw new ResultException("该邮箱邮被注册");
        }

        String code = randomGenerator.generate();
        String message = eMailUtils.formatterVerifyCodeTemplateContent(code);
        eMailUtils.send(email, message);
        // 发送成功后写入redis
        redisUtil.set(redisUtil.getKey(RedisConst.EMAIL_VERIFY_CODE, email), code, ymlConfig.getOverdue());
        return true;
    }

    @Override
    public byte[] getImageVerifyCode() {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 50);
        lineCaptcha.setGenerator(randomGenerator);
        String sessionId = httpServletRequest.getSession().getId();
        redisUtil.set(redisUtil.getKey(RedisConst.IMAGE_VERIFY_CODE, sessionId), lineCaptcha.getCode(), ymlConfig.getImageCodeOverdue());
        return lineCaptcha.getImageBytes();
    }

    @Override
    public Boolean sendVerifyCodeBySms(String phone, boolean registered) {
        return null;
    }

    /**
     * 校验验证码 -- 注意 这里验证完成并返回结果后会主动销毁验证码
     * @param key key
     * @param code 用户传入的验证码
     * @return Boolean
     */
    private Boolean verifyCode(String key, String code, boolean isDel) {
        String cacheCode = (String) redisUtil.get(key);

        if (!StringUtils.hasText(cacheCode)) {
            throw new ResultException("验证码无效或已过期");
        }

        if (!cacheCode.equals(code)) {
            throw new ResultException("验证码错误");
        }

        if (isDel) {
            redisUtil.del(key);
        }
        return true;
    }

    private Boolean verifyCode(String key, String code) {
        return verifyCode(key, code, true);
    }

    @Override
    public Boolean verifyEmailCode(String email, String code) {
        return verifyCode(redisUtil.getKey(RedisConst.EMAIL_VERIFY_CODE, email), code);
    }

    @Override
    public Boolean verifyImageCode(String code) {
        String sessionId = httpServletRequest.getSession().getId();
        return verifyCode(redisUtil.getKey(RedisConst.IMAGE_VERIFY_CODE, sessionId), code);
    }
}
